﻿#include "ffmpeg_command_demo.h"
#include "ui_ffmpeg_command_demo.h"
#include "src/ffmpeg/ffmpeg_process.h"
#include "src/ffmpeg/ffmpeg_command.h"
#include <QStringList>
#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>


// QDir::NoDotAndDotDot  这个筛选条件一定要加上， 否则结果 会多出两个  "."  , ".." 的文件夹，在递归的时候会死循环
QFileInfoList lcl_getFileList(const QString& sPath )

{
    QFileInfoList result;
    QDir dir(sPath );

    dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks | QDir::Dirs | QDir::NoDotAndDotDot);
    dir.setSorting(QDir::Time | QDir::Reversed);

    QFileInfoList fileInfoList = dir.entryInfoList();
    foreach (QFileInfo fileInfo, fileInfoList)
    {
        if(fileInfo.isDir())
        {
            result.append(lcl_getFileList(fileInfo.filePath()));
        }
        else
        {
            result.append(fileInfo);

        }
    }

    return result;
}


FFmpegCommandDemo::FFmpegCommandDemo(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ffmpeg_command_demo)
{
    ui->setupUi(this);

    connect(ui->fileListWd, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(fileListItemDoubleClicked(QListWidgetItem*)));
    connect(ui->fileListToCutWd, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(fileListToCutItemDoubleClicked(QListWidgetItem*)));

    ui->mergeProgressBar->setVisible(false);
    ui->mergeProgressLbl->setVisible(false);
}

FFmpegCommandDemo::~FFmpegCommandDemo()
{
    delete ui;
}

void FFmpegCommandDemo::on_thumbnailsBtn_clicked()
{
    if (m_videoToGifPath.isEmpty())
        return;

    QString outFile = qApp->applicationDirPath() + "/1.png";
    FFmpegProcess* process = new FFmpegProcess(this);
    process->start(FFmpegCommand::thumbnails(m_videoToGifPath, outFile));

    m_convertedFilePath = outFile;
    // open png when convert finished
    connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onConvertFinished(int,QProcess::ExitStatus)));
}


void FFmpegCommandDemo::on_addFileBtn_clicked()
{
    m_videoToGifPath = QFileDialog::getOpenFileName(this,
        tr("Add Video"), "", tr("Video Files (*.mp4;*.mkv;*.mov;*.avi;*.wmv;*.m4v;*.mpg;*.vob;*.webm;*.ogv;*.3gp;*.flv;*.f4v;*.swf)"));

    ui->videoToThumnailsLbl->setText(m_videoToGifPath);
}

void FFmpegCommandDemo::onConvertFinished(int exitCode, QProcess::ExitStatus /*exitStatus*/)
{
    ui->mergeProgressBar->setVisible(false);
    ui->mergeProgressLbl->setVisible(false);

    m_bMerging = false;

    if (exitCode == 0) {
        QProcess* processOpenFile = new QProcess(this);
        QStringList args;
        args << m_convertedFilePath.replace("/", "\\"); // Windows下的 explorer需要反斜杠
        qDebug() << "openfile: explorer " << args;
        processOpenFile->start("explorer", args);
    }
}


void FFmpegCommandDemo::on_addFileToMergeBtn_clicked()
{
    QStringList fileNames = QFileDialog::getOpenFileNames(this,
        tr("Add Video"), "", tr("Video Files (*.mp4;*.mkv;*.mov;*.avi;*.wmv;*.m4v;*.mpg;*.vob;*.webm;*.ogv;*.3gp;*.flv;*.f4v;*.swf)"));
    foreach (QString fileName, fileNames) {
        QListWidgetItem* item = new QListWidgetItem;
        item->setText(fileName);
        item->setData(0, fileName);
        ui->fileListWd->addItem(item);
    };
}

void FFmpegCommandDemo::fileListItemDoubleClicked(QListWidgetItem */*item*/)
{
    QList<QListWidgetItem*> items = ui->fileListWd->selectedItems();
    foreach(QListWidgetItem* item, items)
    {
        delete ui->fileListWd->takeItem(ui->fileListWd->row(item));
    }
}

void FFmpegCommandDemo::fileListToCutItemDoubleClicked(QListWidgetItem *item)
{
    QList<QListWidgetItem*> items = ui->fileListToCutWd->selectedItems();
    items = ui->fileListToCutWd->selectedItems();
    foreach(QListWidgetItem* item, items)
    {
        delete ui->fileListToCutWd->takeItem(ui->fileListToCutWd->row(item));
    }
}

void FFmpegCommandDemo::on_mergeVideoBtn_clicked()
{
    if (ui->fileListWd->count() < 2) {
        QMessageBox::information(this, "Tips", "Please add 2 or more files first");
        return;
    }


    if (m_bMerging) {
        // 当前正在转换
        return;
    }
    m_bMerging = true;


    QString outFile = qApp->applicationDirPath() + "/out.mp4";
    FFmpegProcess* process = new FFmpegProcess(this);
    connect(process, SIGNAL(onProgress(double)), this, SLOT(onUpdateMergeProgress(double)));

    QStringList items;
    for(int i = 0; i < ui->fileListWd->count(); ++i) {
        QString path = ui->fileListWd->item(i)->data(0).toString();
        items << path;
    }
    process->start(FFmpegCommand::mergeVideo(items, outFile));

    m_convertedFilePath = outFile;
    // open png when convert finished
    connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onConvertFinished(int,QProcess::ExitStatus)));
}

void FFmpegCommandDemo::onUpdateMergeProgress(double progress)
{
    ui->mergeProgressBar->setVisible(true);
    ui->mergeProgressLbl->setVisible(true);

    ui->mergeProgressBar->setValue(progress);
    ui->mergeProgressLbl->setText(QString::number(progress,'f',2) + "%");
}


void FFmpegCommandDemo::on_addVideoToGifBtn_clicked()
{
    m_videoToGifConvertedFilePath = QFileDialog::getOpenFileName(this,
                tr("Add Video"), "", tr("Video Files (*.mp4;*.mkv;*.mov;*.avi;*.wmv;*.m4v;*.mpg;*.vob;*.webm;*.ogv;*.3gp;*.flv;*.f4v;*.swf)"));

    ui->videoToGifFilePath->setText(m_videoToGifConvertedFilePath);
}


void FFmpegCommandDemo::on_makeGifBtn_clicked()
{
    if (m_videoToGifConvertedFilePath.isEmpty())
        return;

    QString outFile = qApp->applicationDirPath() + "/out.gif";
    FFmpegProcess* process = new FFmpegProcess(this);
    process->start(FFmpegCommand::videoToGif(m_videoToGifConvertedFilePath, outFile, "00:00:00", "00:00:03", "100"));

    m_convertedFilePath = outFile;
    // open png when convert finished
    connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onConvertFinished(int,QProcess::ExitStatus)));
}

void FFmpegCommandDemo::on_addFileToCutBtn_clicked()
{
    QStringList fileNames = QFileDialog::getOpenFileNames(this,
        tr("Add Video"), "", tr("Video Files (*.mp4;*.mkv;*.mov;*.avi;*.wmv;*.m4v;*.mpg;*.vob;*.webm;*.ogv;*.3gp;*.flv;*.f4v;*.swf)"));
    foreach (QString fileName, fileNames) {
        QListWidgetItem* item = new QListWidgetItem;
        item->setText(fileName);
        item->setData(0, fileName);
        ui->fileListToCutWd->addItem(item);
    };
}


void FFmpegCommandDemo::on_cutVideoBtn_clicked()
{
    for(int i = 0; i < ui->fileListToCutWd->count(); ++i) {
        QString path = ui->fileListToCutWd->item(i)->data(0).toString();
        QString outFile = qApp->applicationDirPath() + QString("/out%1.mp4").arg(i);
        FFmpegProcess* process = new FFmpegProcess(this);
        process->start(FFmpegCommand::cropAndCutVideo(path, outFile));

        m_convertedFilePath = outFile;
        // open png when convert finished
        connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onConvertFinished(int,QProcess::ExitStatus)));
    }
}


void FFmpegCommandDemo::on_addDirtoConvertBtn_clicked()
{
    m_dirToConvert = QFileDialog::getExistingDirectory(this);

    // 重新添加
    ui->fileListToConvertWd->clear();

    QFileInfoList fileInfoList = lcl_getFileList(m_dirToConvert);
    foreach (QFileInfo fileInfo, fileInfoList) {
        QListWidgetItem* item = new QListWidgetItem;
        item->setText(fileInfo.absoluteFilePath());
        item->setData(0, fileInfo.absoluteFilePath());
        ui->fileListToConvertWd->addItem(item);
    };
}


void FFmpegCommandDemo::on_addFileToConvertBtn_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
        tr("Add Video"), "", tr("Video Files (*.mp4;*.mkv;*.mov;*.avi;*.wmv;*.m4v;*.mpg;*.vob;*.webm;*.ogv;*.3gp;*.flv;*.f4v;*.swf)"));

    QListWidgetItem* item = new QListWidgetItem;
    item->setText(fileName);
    item->setData(0, fileName);
    ui->fileListToConvertWd->addItem(item);
}


void FFmpegCommandDemo::on_pushButton_clicked()
{

}


void FFmpegCommandDemo::on_convertVideoBtn_clicked()
{
    QStringList items;
    for(int i = 0; i < ui->fileListToConvertWd->count(); ++i) {
        QString infile = ui->fileListToConvertWd->item(i)->data(0).toString();

        QString outfile;
        QString tmp = infile;
        tmp.replace(m_dirToConvert, "");
        tmp = tmp.left(tmp.lastIndexOf("."));
        tmp += ".mp4";
        outfile = m_convertedVideoPath + "/" + tmp;

        //解析出路径（不含文件名）和文件名
        int first = outfile.lastIndexOf ("/");
        QString name = outfile.right (outfile.length ()-first-1);
        QString filePath = outfile.left (first);
        //如果路径不存在，则创建
        QDir dir;
        if(!dir.exists(filePath)){
            dir.mkpath(filePath);
        }

        FFmpegProcess* process = new FFmpegProcess(this);
        connect(process, SIGNAL(onProgress(double)), this, SLOT(onUpdateMergeProgress(double)));


        process->start(FFmpegCommand::convertVideo(infile, outfile));
        // open png when convert finished
        connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onConvertFinished(int,QProcess::ExitStatus)));
    }

    m_convertedFilePath = m_convertedVideoPath;
}

